package org.ccay.excel.importer.internal.impl;

import java.util.ResourceBundle;

import javax.inject.Inject;
import javax.inject.Named;

import org.ccay.async.AsyncMessage;
import org.ccay.async.IMessageProcessor;
import org.ccay.async.task.service.IImportTaskService;
import org.ccay.core.exception.ApplicationException;
import org.ccay.core.log.CcayLoggerFactory;
import org.ccay.core.log.ILogger;
import org.ccay.core.request.impl.RequestContext;
import org.ccay.excel.exception.ExcelImportException;
import org.ccay.excel.exception.ExcelValidationException;
import org.ccay.excel.importer.ExcelImportConstants;
import org.ccay.excel.importer.ExcelImportRequest;
import org.ccay.excel.importer.service.IExcelImportSupport;
import org.ccay.excel.importer.service.impl.internal.ExcelImportContext;
import org.ccay.excel.importer.service.impl.internal.ExcelStreamReaderSax;
import org.ccay.excel.importer.service.impl.internal.ImportMonitor;
import org.ccay.excel.importer.service.impl.internal.InstantiatingNullHandler;
import org.ccay.excel.util.impl.ExcelUtil;
//import org.ccay.mail.service.IMailService;
import org.ccay.message.service.IPushMessageService;

import ognl.OgnlRuntime;

/**
 * Excel导入处理器。
 * 	
 * @author chaowangbang
 * @since Mar 13, 2012
 */
@Named
public class ExcelImportProcessor implements IMessageProcessor {
	
	/** 日志记录器 **/
	private final ILogger logger = CcayLoggerFactory.getLogger(ExcelImportProcessor.class);
	
	
	
	@Inject
	private IImportTaskService importTaskService;
	
	@Inject
	private ResourceBundle resourceBundle;
	
	/**
	 * 异步的邮件服务
	 */
//	@Inject
//	@Named("defaultMailService")
//	private IMailService defaultMailService;
	
	
	/** 消息推送服务 **/
	@Inject
	private IPushMessageService pushMessageService;

	/* (non-Javadoc)
	 * @see org.ccay.async.IMessageProcessor#process(org.ccay.async.AsyncMessage)
	 */
	public void process(AsyncMessage message) throws ApplicationException {
		// 消息到达后的处理
		ExcelImportRequest importRequest = (ExcelImportRequest)message.getContent();
		
		// 语言设置
		String userLanguage = importRequest.getUserLanguage();
		RequestContext.getCurrent().setItem("UserLanguage", userLanguage);
		
		try {
			importExcel(importRequest);
		} catch (ApplicationException ex) {
			logger.error("The exception occured during importing excel."+ex);
		}
	}
	
	/** 处理整个excel文件	
	 * @author chaowangbang
	 * @since Mar 15, 2012
	 * @param importRequest
	 */
	protected void importExcel(ExcelImportRequest importRequest) throws ApplicationException {
		/**
		 * excel导入监视器，监视整个excel文件导入的过程，记录错误，根据条件中断导入操作
		 */ 
		ImportMonitor monitor = new ImportMonitor(importRequest);
		monitor.setImportTaskService(importTaskService);
//		monitor.setDefaultMailService(defaultMailService);
		monitor.setPushMessageService(pushMessageService);
		
		// 开始excel导入任务
		monitor.begin();
		try {
			// 模块用户提供的excel导入支持
			IExcelImportSupport support = getImportSupport(importRequest.getExcelType());

			/**
			 * 构造一个excel导入上下文
			 */
			ExcelImportContext context = new ExcelImportContext(importRequest, support);
			context.setResourceBundle(resourceBundle);
			
			context.setMaxAllowedErrors(context.getMaxAllowedErrors());
			monitor.setImportContext(context);
			
			OgnlRuntime.setNullHandler(Object.class, new InstantiatingNullHandler());

			ExcelStreamReaderSax processor = new ExcelStreamReaderSax(context);
			processor.process();
			//如果数据导入的是空的 那么异常
			if(0==context.getProcessedCount()){
				throw new ExcelImportException(ExcelImportConstants.EXCEL_TEMPLATE_NO_DATA_IN_EXCEL);
			}
			// excel导入任务顺利结束
			monitor.end();
		}catch (ExcelValidationException eve) {
			logger.error(eve);
			monitor.fail4Validation(eve);
		}catch (ExcelImportException eie) {
			logger.error(eie);
			monitor.fail(eie);
		}catch (RuntimeException rex) {
			// 记录错误日志
			logger.error(rex);
			monitor.fail(rex);
		}catch (Exception ex) {
			logger.error(ex);
			monitor.fail(ex);
		}catch(Error er){
			//记录Error但不处理
			logger.error(er);
			monitor.fail(er);
			throw er;
		}
	}
	
	/** 
	 * 获取导入支持Bean
	 * @param excelType
	 * @return
	 * @throws ApplicationException 
	 */
	private IExcelImportSupport getImportSupport(String excelType) throws ApplicationException {
		return ExcelUtil.getImportSupport(excelType);
	}

}
